def build(a, d, b, s, t, p):
    # 对 [s,t] 区间建立线段树,当前根的编号为 p
    if s == t:
        d[p] = a[s]
        return
    m = s + ((t - s) >> 1)
    # 移位运算符的优先级小于加减法，所以加上括号
    # 如果写成 (s + t) >> 1 可能会超出 int 范围
    build(a, d, b, s, m, p * 2)
    build(a, d, b, m + 1, t, p * 2 + 1)
    # 递归对左右区间建树
    d[p] = d[p * 2] + d[(p * 2) + 1]


def update(a, d, b, l, r, c, s, t, p):
    # [l, r] 为修改区间, c 为被修改的元素的变化量, [s, t] 为当前节点包含的区间, p
    # 为当前节点的编号
    if l <= s and t <= r:
        d[p] = d[p] + (t - s + 1) * c
        b[p] = b[p] + c
        return
    # 当前区间为修改区间的子集时直接修改当前节点的值, 然后打标记, 结束修改
    m = s + ((t - s) >> 1)
    if b[p] and s != t:
        # 如果当前节点的懒标记非空, 则更新当前节点两个子节点的值和懒标记值
        d[p * 2] = d[p * 2] + b[p] * (m - s + 1)
        d[p * 2 + 1] = d[p * 2 + 1] + b[p] * (t - m)
        # 将标记下传给子节点
        b[p * 2] = b[p * 2] + b[p]
        b[p * 2 + 1] = b[p * 2 + 1] + b[p]
        # 清空当前节点的标记
        b[p] = 0
    if l <= m:
        update(a, d, b, l, r, c, s, m, p * 2)
    if r > m:
        update(a, d, b, l, r, c, m + 1, t, p * 2 + 1)
    d[p] = d[p * 2] + d[p * 2 + 1]


def get_sum(a, d, b, l, r, s, t, p):
    # [l, r] 为查询区间, [s, t] 为当前节点包含的区间, p为当前节点的编号
    if l <= s and t <= r:
        return d[p]
    # 当前区间为询问区间的子集时直接返回当前区间的和
    m = s + ((t - s) >> 1)
    if b[p]:
        # 如果当前节点的懒标记非空, 则更新当前节点两个子节点的值和懒标记值
        d[p * 2] = d[p * 2] + b[p] * (m - s + 1)
        d[p * 2 + 1] = d[p * 2 + 1] + b[p] * (t - m)
        # 将标记下传给子节点
        b[p * 2] = b[p * 2] + b[p]
        b[p * 2 + 1] = b[p * 2 + 1] + b[p]
        # 清空当前节点的标记
        b[p] = 0
    sum = 0
    if l <= m:
        sum = get_sum(a, d, b, l, r, s, m, p * 2)
    if r > m:
        sum = sum + get_sum(a, d, b, l, r, m + 1, t, p * 2 + 1)
    return sum


def solve(arr, ops):
    a = [0] + arr
    n = len(arr)
    d = [0] * (4*n)
    b = [0] * (4*n)
    build(a, d, b, 1, n, 1)
    result = []
    for i, (op, l, r, c) in enumerate(ops):
        if op == 1:
            update(a, d, b, l, r, c, 1, n, 1)
        else:
            result.append(get_sum(a, d, b, l, r, 1, n, 1))
        # print(d)
    return result


def brutal_solve(arr, ops):
    import numpy as np
    a = np.asarray([0] + arr)
    result = []
    for i, (op, l, r, c) in enumerate(ops):
        if op == 1:
            a[l: r+1] += c
        else:
            result.append(sum(a[l: r+1]))
    return result


def test():
    n_cases = 10000
    max_n = 10
    max_op = 100

    import random
    for _ in range(n_cases):
        n = random.randint(1, max_n)
        arr = list(range(1, n+1))
        ops = []
        for _ in range(max_op):
            op = random.randint(1, 2)
            l, r = sorted([random.randint(1, n), random.randint(1, n)])
            c = random.randint(-2, 2) if op == 1 else 0
            ops.append([op, l, r, c])
        res1 = solve(arr, ops)
        res2 = brutal_solve(arr, ops)
        if res1 != res2:
            print(arr, ops, res1, res2, sep=', ')
test()